/* * Sun Public License Notice * * The contents of this file are subject to the Sun Public License * Version 1.0 (the "License"). You may not use this file except in * compliance with the License. A copy of the License is available at * http://www.sun.com/ * * The Original Code is Forte for Java, Community Edition. The Initial * Developer of the Original Code is Sun Microsystems, Inc. Portions * Copyright 1997-2000 Sun Microsystems, Inc. All Rights Reserved. */ package org.openide.awt; import java.awt.Component; import java.awt.BorderLayout; import java.awt.FlowLayout; import java.awt.EventQueue; import java.awt.event.*; import java.util.*; import javax.swing.*; import org.openide.*; import org.openide.loaders.*; import org.openide.cookies.InstanceCookie; import org.openide.util.RequestProcessor; import org.openide.util.Task; /** * This class keeps track of the current toolbars and their names. * @author David Peroutka, Libor Kramolis */ public final class ToolbarPool extends JComponent { /** Default ToolbarPool */ private static ToolbarPool defaultPool; /** objects responsible for creation of the window */ private static Folder instance; /** DataFolder from which the pool was created */ private static DataFolder folder; /** Maps name to <code>Toolbar</code>s */ private static Map toolbars; /** Maps name to <code>ToolbarPool.Configuration</code>s */ private static Map toolbarConfigs; /** Current name of selected configuration */ private static String name = ""; // NOI18N /** Center component */ private static Component center; /** Popup menu listener */ private static PopupListener listener; /** * Returns default toolbar pool. * @return default system pool */ public static ToolbarPool getDefault () { if (defaultPool == null) { synchronized (ToolbarPool.class) { if (defaultPool == null) { defaultPool = new ToolbarPool ( TopManager.getDefault ().getPlaces ().folders ().toolbars () ); // we mustn't do this in constructor to prevent from // nevereding recursive calls to this method. defaultPool.instance.recreate(); } } } return defaultPool; } static final long serialVersionUID =3420915387298484008L; /** * Creates a new <code>ToolbarPool</code>. */ private ToolbarPool (DataFolder df) { folder = df; setLayout (new BorderLayout ()); listener = new PopupListener(); toolbars = new TreeMap(); toolbarConfigs = new TreeMap(); instance = new Folder (df); } /** Allows to wait till the content of the pool is initialized. */ public void waitFinished () { instance.instanceFinished (); } /** Initialization of new values. * @param toolbars map (String, Toolbar) of toolbars * @param conf map (String, Configuration) of configs */ void update (Map toolbars, Map conf) { this.toolbars = toolbars; this.toolbarConfigs = conf; setConfiguration (name); // Configuration c = (Configuration)toolbarConfigs.get (name); // if (c != null) { // activate (c); // } else if (toolbarConfigs.isEmpty()) { // updateDefault (); // } else { // c = (Configuration)toolbarConfigs.values().iterator().next(); // activate (c); // } } /** Updates the default configuration. */ private synchronized void updateDefault () { JPanel tp = new JPanel (new FlowLayout (FlowLayout.LEFT)); Toolbar[] list = getToolbars (); for (int i = 0; i < list.length; i++) { tp.add (list[i]); } name = ""; // NOI18N revalidate (tp); } /** Activates a configuration. * @param c configuration */ private synchronized void activate (Configuration c) { Component comp = c.activate (); name = c.getName(); revalidate (comp); } /** Sets DnDListener to all Toolbars. */ public void setToolbarsListener (Toolbar.DnDListener l) { Iterator it = toolbars.values().iterator(); while (it.hasNext()) ((Toolbar)it.next()).setDnDListener (l); } /** Uses new component as a cental one. */ private void revalidate (Component c) { if (c != center) { // exchange if (center != null) { remove (center); center.removeMouseListener (listener); } add (center = c, BorderLayout.CENTER); center.addMouseListener (listener); } //revalidate (); invalidate (); validate (); repaint (); // Dafe - this breaks main windoe positioning... /*java.awt.Window w = javax.swing.SwingUtilities.windowForComponent (this); if (w != null) { w.pack (); }*/ // Libor - Dafe's fix breaks main window resizing... java.awt.Window w = javax.swing.SwingUtilities.windowForComponent (this); if (w != null) { w.validate (); } } // public void updateUI () { // super.updateUI(); // revalidate (center); // } /** * Returns a <code>Toolbar</code> to which this pool maps the given name. * @param name a <code>String</code> that is to be a toolbar's name * @return a <code>Toolbar</code> to which this pool maps the name */ public Toolbar findToolbar (String name) { return (Toolbar)toolbars.get (name); } /** * Getter for the name of current configuration. * @return the name of current configuration */ public String getConfiguration () { return name; } /** * Switch to toolbar configuration by specific config name * @param name toolbar configuration name */ public void setConfiguration (String n) { // instance.waitFinished (); if (!instance.isFinished()) return; Configuration config = null; if (n != null) { config = (Configuration)toolbarConfigs.get (n); } if (config != null) { // if configuration found activate (config); } else if (toolbarConfigs.isEmpty()) { // if no toolbar configuration updateDefault (); } else if (center == null) { // bad config name (n) and no configuration activated yet config = (Configuration)toolbarConfigs.values().iterator().next(); activate (config); } } /** * @return the <code>DataFolder</code> from which the pool was created. */ public DataFolder getFolder() { return folder; } /** * Returns the toolbars contained in this pool. * @return the toolbars contained in this pool */ public synchronized Toolbar[] getToolbars() { Toolbar[] arr = new Toolbar[toolbars.size ()]; return (Toolbar[])toolbars.values ().toArray (arr); } /** * @return the names of toolbar configurations contained in this pool */ public synchronized String[] getConfigurations () { String[] arr = new String[toolbarConfigs.size ()]; return (String[])toolbarConfigs.keySet ().toArray (arr); } /** * This class can be used to produce a <code>ToolbarPool</code> instance * from the given <code>DataFolder</code>. */ private class Folder extends FolderInstance { private WeakHashMap foldersCache = new WeakHashMap (15); /** the <code>ToolbarPool</code> to work with */ private ToolbarPool toolbarPool; public Folder (DataFolder f) { super (f); } /** * Full name of the data folder's primary file separated by dots. * @return the name */ public String instanceName () { return instanceClass().getName(); } /** * Returns the root class of all objects. * @return Object.class */ public Class instanceClass () { return ToolbarPool.class; } /** * Accepts only cookies that can provide <code>Configuration</code>. * @param cookie the instance cookie to test * @return true if the cookie can provide <code>Configuration</code> */ protected InstanceCookie acceptCookie (InstanceCookie cookie) throws java.io.IOException, ClassNotFoundException { Class cls = cookie.instanceClass(); if (ToolbarPool.Configuration.class.isAssignableFrom (cls)) { return cookie; } if (Component.class.isAssignableFrom (cls)) { return cookie; } return null; } /** * Returns a <code>Toolbar.Folder</code> cookie for the specified * <code>DataFolder</code>. * @param df a <code>DataFolder</code> to create the cookie for * @return a <code>Toolbar.Folder</code> for the specified folder */ protected InstanceCookie acceptFolder (DataFolder df) { InstanceCookie ic = (InstanceCookie)foldersCache.get (df); if (ic == null) { ic = new Toolbar.Folder (df); foldersCache.put (df, ic); } return ic; } /** * Updates the <code>ToolbarPool</code> represented by this folder. * * @param cookies array of instance cookies for the folder * @return the updated <code>ToolbarPool</code> representee */ protected Object createInstance (InstanceCookie[] cookies) throws java.io.IOException, ClassNotFoundException { final int length = cookies.length; Map toolbars = new TreeMap (); Map conf = new TreeMap (); for (int i = 0; i < length; i++) { try { Object obj = cookies[i].instanceCreate(); if (obj instanceof Toolbar) { Toolbar toolbar = (Toolbar)obj; // should be done by ToolbarPanel in add method toolbar.removeMouseListener (listener); toolbar.addMouseListener (listener); // if (toolbar.getComponentCount() > 0) // TEMPORARY toolbars.put (toolbar.getName (), toolbar); continue; } if (obj instanceof Configuration) { Configuration config = (Configuration)obj; String name = config.getName (); if (name == null) { name = cookies[i].instanceName (); } conf.put (name, config); continue; } if (obj instanceof Component) { Component comp = (Component)obj; String name = comp.getName (); if (name == null) { name = cookies[i].instanceName (); } conf.put (name, new ComponentConfiguration (comp)); continue; } } catch (java.io.IOException ex) { TopManager.getDefault ().notifyException (ex); } catch (ClassNotFoundException ex) { TopManager.getDefault ().notifyException (ex); } } update (toolbars, conf); return ToolbarPool.this; } } // end of Folder /** * Class to showing popup menu */ private class PopupListener extends MouseUtils.PopupMouseAdapter { /** * Called when the sequence of mouse events should lead to actual showing popup menu */ protected void showPopup (MouseEvent e) { Configuration conf = (Configuration)toolbarConfigs.get (name); if (conf != null) { JPopupMenu pop = conf.getContextMenu(); pop.show (e.getComponent (), e.getX (), e.getY ()); } } } // end of PopupListener /** * Abstract class for toolbar configuration */ public static interface Configuration { /** Activates the configuration and returns right * component that can display the configuration. * @return representation component */ public abstract Component activate (); /** Name of the configuration. * @return the name */ public abstract String getName (); /** Popup menu that should be displayed when the users presses * right mouse button on the panel. This menu can contain * contains list of possible configurations, additional actions, etc. * * @return popup menu to be displayed */ public abstract JPopupMenu getContextMenu (); } /** Implementation of configuration that reacts to one * component */ private static final class ComponentConfiguration extends JPopupMenu implements Configuration, ActionListener { private Component comp; static final long serialVersionUID =-409474484612485719L; /** @param comp component that represents this configuration */ public ComponentConfiguration (Component comp) { this.comp = comp; } /** Simply returns the representation component */ public Component activate () { return comp; } /** @return name of the component */ public String getName () { return comp.getName (); } /** Updates items in popup menu and returns itself. */ public JPopupMenu getContextMenu () { removeAll (); // generate list of available toolbar panels Iterator it = Arrays.asList (ToolbarPool.getDefault ().getConfigurations ()).iterator (); ButtonGroup bg = new ButtonGroup (); String current = ToolbarPool.getDefault ().getConfiguration (); while (it.hasNext()) { final String name = (String)it.next (); JRadioButtonMenuItem mi = new JRadioButtonMenuItem (name, (name.compareTo (current) == 0)); mi.addActionListener (this); bg.add (mi); this.add (mi); } return this; } /** Reacts to action in popup menu. Switches the configuration. */ public void actionPerformed (ActionEvent evt) { ToolbarPool.getDefault().setConfiguration (evt.getActionCommand ()); } } } // end of ToolbarPool /* * Log * 31 Gandalf 1.30 1/18/00 Jaroslav Tulach Configuration can be * component with getName () => null * 30 Gandalf 1.29 1/16/00 Libor Kramolis * 29 Gandalf 1.28 1/13/00 Ian Formanek NOI18N * 28 Gandalf 1.27 1/12/00 Ian Formanek NOI18N * 27 Gandalf 1.26 12/17/99 Libor Kramolis * 26 Gandalf 1.25 10/22/99 Ian Formanek NO SEMANTIC CHANGE - Sun * Microsystems Copyright in File Comment * 25 Gandalf 1.24 8/18/99 Ian Formanek Generated serial version * UID * 24 Gandalf 1.23 8/17/99 David Simonek persistent main window * positioning issues * 23 Gandalf 1.22 8/9/99 Ian Formanek Generated Serial Version * UID * 22 Gandalf 1.21 7/29/99 Libor Kramolis * 21 Gandalf 1.20 7/22/99 Libor Kramolis * 20 Gandalf 1.19 7/22/99 Ian Formanek Fixed Bug # 1957 - * Creating new package under Session Settings | Toolbars node causes * disappearance of Component Pallete and added items to this new package * aren't displayed. Fixed Bug #2085 - After first startup toolbars are * inconsistent, component palette missing. * 19 Gandalf 1.18 6/22/99 Libor Kramolis * 18 Gandalf 1.17 6/17/99 David Simonek various serialization * bugfixes * 17 Gandalf 1.16 6/8/99 Ian Formanek ---- Package Change To * org.openide ---- * 16 Gandalf 1.15 6/7/99 Jaroslav Tulach #2080 * 15 Gandalf 1.14 6/4/99 Libor Kramolis * 14 Gandalf 1.13 5/15/99 Libor Kramolis * 13 Gandalf 1.12 5/13/99 Libor Kramolis * 12 Gandalf 1.11 5/11/99 Jaroslav Tulach ToolbarPool changed to * look better in Open API * 11 Gandalf 1.10 5/10/99 Jesse Glick [JavaDoc] - removed * stuff that would not look good in public from JavaDoc. * 10 Gandalf 1.9 5/10/99 Ian Formanek Patched to compile * 9 Gandalf 1.8 5/7/99 Libor Kramolis * 8 Gandalf 1.7 4/8/99 Libor Kramolis * 7 Gandalf 1.6 4/7/99 Libor Kramolis * 6 Gandalf 1.5 4/4/99 Ian Formanek Latest Libor's version * 5 Gandalf 1.4 3/30/99 Ian Formanek FolderInstance creation * in single thread * 4 Gandalf 1.3 3/26/99 Libor Kramolis * 3 Gandalf 1.2 3/24/99 Libor Kramolis * 2 Gandalf 1.1 3/9/99 Ian Formanek * 1 Gandalf 1.0 2/17/99 Ian Formanek * $ */